﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TVGuide.DataAccess.Exceptions;
using TVGuide.DataAccess.Common;

namespace TVGuide.DataAccess.Repository
{
    public class CountryRepository: ICountryRepository
    {
        #region Singleton pattern

        private static tvchanneldbEntities model;
        private static CountryRepository instance;

        private CountryRepository() 
        {
            model = new tvchanneldbEntities(); 
            maxId = model.countries.Count(); 
        }

        public static CountryRepository Instance()
        {
            if (instance == null)
                instance = new CountryRepository();
            return instance;
        }

        #endregion

        #region IRepository<Country> Members

        public void Add(Country item)
        {
            Add(item, true);
        }

        public void Add(Country item, bool commitChange)
        {
            if (item == null)
                throw new InvalidArgsException("The parameter is null");

            if (String.IsNullOrEmpty(item.Name))
                throw new InvalidArgsException("The 'countryName' field is null");

            
            if (maxId == 0)
                item.Id = 1;
            else
            {
                item.Id = (short)++maxId;
            }

            model.countries.AddObject((country)item);
            if(commitChange)
                model.SaveChanges();
        }

        public void AddRange(IEnumerable<Common.Country> items)
        {
            try
            {
                foreach (var item in items)
                {
                    Add(item, false);
                }
            }
            catch (InvalidArgsException e)
            {
                // TODO rollback changes.
                InvalidArgsException ex = new InvalidArgsException(e.Message + "\nNo items were committed.");
                throw ex;
            }
            model.SaveChanges();
        }

        public Country Get(int id)
        {
            return (Country)model.countries.FirstOrDefault(o => o.countryID == id);
        }

        public IEnumerable<Country> Get(Predicate<Country> func)
        {
            List<Country> list = new List<Country>();
            foreach (var item in model.countries)
            {
                Country cloneObj = (Country)item;
                if (func((Country)item))
                    list.Add(cloneObj);
            }
            return list;
        }

        public IEnumerable<Country> GetAllItems()
        {
            return Get(o => true);
        }

        public void Remove(int id)
        {
            country co = model.countries.FirstOrDefault(o => o.countryID == id);
            if (co != null)
                model.countries.DeleteObject(co);
            model.SaveChanges();
        }

        public void Remove(Predicate<Country> func)
        {
            List<country> removeList = new List<country>();
            foreach (var item in model.countries)
            {
                if (func((Country)item))
                    removeList.Add(item);
            }
            foreach (var item in removeList)
            {
                model.countries.DeleteObject(item);
            }
            model.SaveChanges();
        }

        public void RemoveAll()
        {
            Remove(o => true);
        }

        #endregion

        private int maxId;
    }
}
